package com.qzboot.facade.common;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.util.TypeUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zengzhihong
 * @date 2019-04-17
 */
@Slf4j
public class MpSupport {

    /**
     * ID字段名
     */
    public static final String ID_COLUMN = "id";

    public static final String LIKE = "#%#";

    /**
     * 大于
     */
    public static final String GT = "#>#";

    /**
     * 大于等于 &gt;=
     */
    public static final String GE = "#>=#";

    /**
     * 小于
     */
    public static final String LT = "#<#";

    /**
     * 小于等于 &gt;=
     */
    public static final String LE = "#<=#";

    /**
     * 创建时间字段名
     */
    public static final String CREATE_TIME_COLUMN = "createTime";

    /**
     * 更新时间字段名
     */
    public static final String UPDATE_TIME_COLUMN = "updateTime";


    public static <T> IPage<T> getPage(Map<String, Object> param) {
        if (null == param) {
            return new Page<>();
        }
        Integer currentPage = TypeUtils.castToInt(param.get("currentPage"));
        Integer pageSize = TypeUtils.castToInt(param.get("pageSize"));
        Page<T> page = new Page<>(null == currentPage ? 1 : currentPage, null == pageSize ? 10 : pageSize);
        String asc = TypeUtils.castToString(param.get("asc"));
        String desc = TypeUtils.castToString(param.get("desc"));
        if (StrUtil.isNotBlank(asc)) {
            for (String s : StrUtil.splitToArray(asc, StrUtil.C_COMMA)) {
                page.addOrder(OrderItem.asc(s));
            }
        }
        if (StrUtil.isNotBlank(desc)) {
            for (String s : StrUtil.splitToArray(desc, StrUtil.C_COMMA)) {
                page.addOrder(OrderItem.desc(desc));
            }
        }
        return page;
    }

    /**
     * 获取MP查询对象
     *
     * @param entity
     * @param <T>
     * @return
     */
    public static <T> QueryWrapper<T> getQueryWrapper(T entity) {
        return Wrappers.query(entity);
    }

    /**
     * 获取MP查询对象
     *
     * @param param
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> param, Class<T> clazz) {
        if (null == param) {
            //TODO throw ex
            return null;
        }
        QueryWrapper<T> qw = new QueryWrapper<>();
        List<String> fieldList = Arrays.stream(ClassUtil.getDeclaredFields(clazz)).map(Field::getName).collect(Collectors.toList());
        qw.setEntity(BeanUtils.instantiateClass(clazz));
        if (CollectionUtil.isNotEmpty(param)) {
            param.forEach((k, v) -> {
                if (!ObjectUtils.isEmpty(v) && fieldList.contains(k)) {
                    k = StrUtil.toUnderlineCase(k);
                    String vStr = v.toString();
                    if (vStr.contains(LIKE)) {
                        qw.like(k, StrUtil.replace(vStr, LIKE, StrUtil.EMPTY));
                    } else if (vStr.contains(GT)) {
                        qw.gt(k, StrUtil.replace(vStr, GT, StrUtil.EMPTY));
                    } else if (vStr.contains(GE)) {
                        qw.ge(k, StrUtil.replace(vStr, GE, StrUtil.EMPTY));
                    } else if (vStr.contains(LT)) {
                        qw.lt(k, StrUtil.replace(vStr, LT, StrUtil.EMPTY));
                    } else if (vStr.contains(LE)) {
                        qw.le(k, StrUtil.replace(vStr, LE, StrUtil.EMPTY));
                    } else {
                        qw.eq(k, v);
                    }

                }
            });
        }
        return qw;
    }

}
